﻿namespace MvcFckEditor.Components
{
    using System;
    using System.Collections;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;

    internal class Config
    {
        public string[] AllowedTypes;
        public string FckBasePath;
        public string[] HtmlExtensions;
        public TypeConfigList TypeConfig;
        public string UserFilesPath;

        internal Config()
        {
            this.DefaultSettings();
        }

        private bool CheckIsNonHtmlExtension(string extension)
        {
            return ((this.HtmlExtensions.Length == 0) || !Util.ArrayContains(this.HtmlExtensions, extension, CaseInsensitiveComparer.DefaultInvariant));
        }

        private bool CheckIsTypeAllowed(string typeName)
        {
            return (Array.IndexOf<string>(this.AllowedTypes, typeName) >= 0);
        }

        private bool CheckNonHtmlFile(HttpPostedFileBase file)
        {
            byte[] buffer = new byte[0x400];
            file.InputStream.Read(buffer, 0, 0x400);
            string input = Encoding.ASCII.GetString(buffer);
            if (Regex.IsMatch(input, @"<!DOCTYPE\W*X?HTML", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "<(?:body|head|html|img|pre|script|table|title)", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "type\\s*=\\s*[\\'\"]?\\s*(?:\\w*/)?(?:ecma|java)", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "(?:href|src|data)\\s*=\\s*[\\'\"]?\\s*(?:ecma|java)script:", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "url\\s*\\(\\s*[\\'\"]?\\s*(?:ecma|java)script:", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            return true;
        }

        private void DefaultSettings()
        {
            this.FckBasePath = "/fckeditor/";
            this.UserFilesPath = FckProvider.Instance().GetUserFilesPath();
            if (this.UserFilesPath.EndsWith("/"))
            {
                this.UserFilesPath = this.UserFilesPath.Substring(0, this.UserFilesPath.Length - 1);
            }
            if (!Directory.Exists(HttpContext.Current.Server.MapPath(this.UserFilesPath)))
            {
                Util.CreateDirectory(HttpContext.Current.Server.MapPath(this.UserFilesPath));
            }
            this.AllowedTypes = new string[] { "File", "Image", "Flash", "Media" };
            this.HtmlExtensions = new string[] { "html", "htm", "xml", "xsd", "txt", "js" };
            this.TypeConfig = new TypeConfigList();
            this.TypeConfig["File"].AllowedExtensions = new string[] { 
                "7z", "aiff", "asf", "avi", "bmp", "csv", "doc", "fla", "flv", "gif", "gz", "gzip", "jpeg", "jpg", "mid", "mov", 
                "mp3", "mp4", "mpc", "mpeg", "mpg", "ods", "odt", "pdf", "png", "ppt", "pxd", "qt", "ram", "rar", "rm", "rmi", 
                "rmvb", "rtf", "sdc", "sitd", "swf", "sxc", "sxw", "tar", "tgz", "tif", "tiff", "txt", "vsd", "wav", "wma", "wmv", 
                "xls", "xml", "zip"
             };
            this.TypeConfig["File"].DeniedExtensions = new string[0];
            this.TypeConfig["File"].FilesPath = this.UserFilesPath;
            this.TypeConfig["Image"].AllowedExtensions = new string[] { "bmp", "gif", "jpeg", "jpg", "png" };
            this.TypeConfig["Image"].DeniedExtensions = new string[0];
            this.TypeConfig["Image"].FilesPath = this.UserFilesPath;
            this.TypeConfig["Flash"].AllowedExtensions = new string[] { "swf", "flv" };
            this.TypeConfig["Flash"].DeniedExtensions = new string[0];
            this.TypeConfig["Flash"].FilesPath = this.UserFilesPath;
            this.TypeConfig["Media"].AllowedExtensions = new string[] { 
                "aiff", "asf", "avi", "bmp", "fla", "flv", "gif", "jpeg", "jpg", "mid", "mov", "mp3", "mp4", "mpc", "mpeg", "mpg", 
                "png", "qt", "ram", "rm", "rmi", "rmvb", "swf", "tif", "tiff", "wav", "wma", "wmv"
             };
            this.TypeConfig["Media"].DeniedExtensions = new string[0];
            this.TypeConfig["Media"].FilesPath = this.UserFilesPath;
        }

        internal string FileUpload(HttpPostedFileBase oFile, string resourceType, string currentFolder, bool isQuickUpload)
        {
            if (resourceType == null)
            {
                return this.SendFileUploadResponse(1, true, "", "", "无效的请求！");
            }
            if (!this.CheckIsTypeAllowed(resourceType))
            {
                return this.SendFileUploadResponse(1, true, "", "", "无效的资源类型请求！");
            }
            string str2 = "";
            if (oFile == null)
            {
                return this.SendFileUploadResponse(0xca, isQuickUpload, "", "", "请选择您要上传的文件！");
            }
            string str3 = this.ServerMapFolder(resourceType, currentFolder, isQuickUpload);
            str2 = Util.SanitizeFileName(Path.GetFileName(oFile.FileName));
            string extension = Path.GetExtension(oFile.FileName).TrimStart(new char[] { '.' });
            if (!this.TypeConfig[resourceType].CheckIsAllowedExtension(extension))
            {
                return this.SendFileUploadResponse(0xca, isQuickUpload, "", "", "您只能上传类型为：" + Util.ArrayToSrting(this.TypeConfig[resourceType].AllowedExtensions) + " 的文件！");
            }
            if (!(!this.CheckIsNonHtmlExtension(extension) || this.CheckNonHtmlFile(oFile)))
            {
                return this.SendFileUploadResponse(0xca, isQuickUpload, "", "", "您不能上传类型为：" + Util.ArrayToSrting(this.TypeConfig[resourceType].DeniedExtensions) + " 的文件！");
            }
            int errorNumber = 0;
            int num2 = 0;
            while (true)
            {
                string path = Path.Combine(str3, str2);
                if (File.Exists(path))
                {
                    num2++;
                    str2 = string.Concat(new object[] { Path.GetFileNameWithoutExtension(oFile.FileName), "(", num2, ").", extension });
                    errorNumber = 0xc9;
                }
                else
                {
                    oFile.SaveAs(path);
                    MvcFckEditor.Components.TypeConfig config = this.TypeConfig[resourceType];
                    string fileUrl = config.FilesPath + "/" + str2;
                    return this.SendFileUploadResponse(errorNumber, isQuickUpload, fileUrl, str2, "上传成功！");
                }
            }
        }

        private string SendFileUploadResponse(int errorNumber, bool isQuickUpload, string fileUrl, string fileName, string customMsg)
        {
            if (!isQuickUpload)
            {
                return customMsg;
            }
            StringBuilder builder = new StringBuilder();
            builder.Append("<script type=\"text/javascript\">");
            builder.Append(@"(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();");
            if (isQuickUpload)
            {
                builder.Append(string.Concat(new object[] { "window.parent.OnUploadCompleted(", errorNumber, ",'", fileUrl.Replace("'", @"\'"), "','", fileName.Replace("'", @"\'"), "','", customMsg.Replace("'", @"\'"), "') ;" }));
            }
            else
            {
                builder.Append(string.Concat(new object[] { "window.parent.frames['frmUpload'].OnUploadCompleted(", errorNumber, ",'", fileName.Replace("'", @"\'"), "') ;" }));
            }
            builder.Append("</script>");
            return builder.ToString();
        }

        private string ServerMapFolder(string resourceType, string folderPath, bool isQuickUpload)
        {
            MvcFckEditor.Components.TypeConfig config = this.TypeConfig[resourceType];
            string path = HttpContext.Current.Server.MapPath(config.FilesPath);
            Util.CreateDirectory(path);
            return Path.Combine(path, folderPath.TrimStart(new char[] { '/' }));
        }
    }
}

